package cn.bluethink.eguan.core.service;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.bluethink.eguan.core.entity.EgUserEntity;
import cn.bluethink.eguan.core.mapper.EgUserMapper;
import cn.bluethink.eguan.model.core.EgAcount;
import cn.bluethink.eguan.model.core.EgBag;
import cn.bluethink.eguan.model.core.EgConfigInfo;
import cn.bluethink.eguan.model.core.EgFaction;
import cn.bluethink.eguan.model.core.EgOType;
import cn.bluethink.eguan.model.core.EgObject;
import cn.bluethink.eguan.model.core.EgRole;
import cn.bluethink.eguan.model.core.EgScope;
import cn.bluethink.eguan.model.core.EgTavern;
import cn.bluethink.eguan.model.core.EgUser;
import cn.bluethink.eguan.utils.IdMakerUtils;
import tk.mybatis.mapper.entity.Example;

/**
 * 
 * @title 苏州中科蓝迪公司所有(c)2016-2021
 * @version 0.1.0
 * @describe
 * @author liuxn
 * 
 * @note 修订历史： （1）liuxn于2018年8月22日构建初始版本0.1 、 （2）liuxn于2018年10月09日添加新增用户方法 （3）
 *       liuxn于2018年11月05日修订钉钉登录获取默认角色权限和设置当前用户角色权限
 * 
 */

@Service
public class EgUserService {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private EgConfigInfo configInfo;

    @Autowired
    private EgUserMapper userMapper;

    @Autowired
    private EgBagService bagService;

    @Autowired
    private EgAcountService acountService;

    @Autowired
    private EgFactionService factionService;

    @Autowired
    private EgMemberService memberService;

    @Autowired
    private EgPosObjectService posObjectService;

    @Autowired
    private EgUserPurviewService userPurviewService;

    private IdMakerUtils idMakerUtil = new IdMakerUtils();

    /**
     * 创建用户 钉钉扫码登录跳转登录url，如果用户不存在会新建一个用户
     * 
     * @param name
     * @param avatar
     * @param unionid
     * @param corpid
     * @param corpname
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public EgUser create(String name, String avatar, String unionid, String corpid, String corpname) throws Exception {
        // 第一步创建用户对应的唯一包裹和账户
        EgBag bag = bagService.create(name + "的包裹");
        if (bag == null) {
            return null;
        }
        EgAcount acount = acountService.create(name + "的账户");
        if (acount == null) {
            return null;
        }
        // 第二步创建用户
        EgUser user = new EgUser(idMakerUtil.nextId(), name, avatar);
        user.setBag(bag);
        user.setAcount(acount);
        // 江湖中默认侠客角色
        EgRole defaultRole = configInfo.role(EgRole.TRAVELER).get(EgScope.WULIN);
        // 定义当前用户为江湖中的侠客
        EgRole role = new EgRole(defaultRole.getRid(), defaultRole.getName(), defaultRole.getPurview());
        role.setName(configInfo.roleName(role.getRid(), EgScope.WULIN));
        user.setRole(role);
        user.setPos(new EgObject(0L, null, new EgOType(EgOType.JIANGHU, null)));
        // 创建用户实体，保存到数据库
        EgUserEntity userEntity = new EgUserEntity(user, unionid);
        if (userMapper.insertSelective(userEntity) == 0) {
            return null;
        }
        // 第三步门派相关处理
        if (corpid == null) {
            // 没有门派，该用户还是江湖中的侠客
            return user;
        } else {
            // 首先根据门派corpid 查找对应的门派信息
            EgFaction faction = factionService.queryByfId(corpid);
            if (faction == null) {
                // 没有门派，创建门派(包含首先创建门派对应唯一账户)
                faction = factionService.create(corpname, "", user.getId(), corpid);
                if (faction == null) {
                    return user;
                }
            }
            // 增加user到门派成员中
            EgUser member = memberService.create(faction.getId(), user.getId());
            if (member == null) {
                return user;
            }
            // 更新用户所在地(门派)到数据库用户信息表中
            userEntity = new EgUserEntity(user.getId(), EgOType.FACTION, faction.getId());
            if (userMapper.updateByPrimaryKeySelective(userEntity) > 0) {
                // 设置用户位置为门派
                user.setPos(new EgObject(faction.getId(), null, new EgOType(EgOType.FACTION, null)));
                // 对用户在江湖中和门派中的角色，进行"或"运算后，更新到用户信息表中。
                role.or(member.getRole());
                role.setName(configInfo.roleName(role.getRid(), EgScope.FACTION));
                user.setRole(role);
                return user;
            }
            return null;
        }
    }

    /**
     * 更新用户信息（包括用户的名称、头像）
     * 
     * @param user
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public EgUser update(EgUser user) throws Exception {
        // 更新操作
        EgUserEntity entity = new EgUserEntity(user);
        entity.setUtime(new Date());
        int updateCount = userMapper.updateByPrimaryKeySelective(entity);
        if (updateCount != 0) {
            user.setuTime(entity.getUtime());
            return user;
        }
        return null;
    }

    /**
     * 更新用户的位置信息
     * 
     * @param uid
     * @param otype
     * @param posoid
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public Boolean updatePos(Long uid, Integer otype, Long posoid) throws Exception {
        EgUserEntity entity = new EgUserEntity(uid, otype, posoid);
        int updateCount = userMapper.updateByPrimaryKeySelective(entity);
        return updateCount > 0 ? true : false;
    }

    /**
     * 查看用户详情信息 包括基本信息(角色、账户等)以及用户位置的详细信息
     * 
     * @param id
     * @return
     * @throws Exception
     */
    public EgUser detail(Long id) throws Exception {
        EgUserEntity entity = userMapper.selectByPrimaryKey(id);
        if (entity == null) {
            return null;
        }
        EgUser user = entity.createUser();
        if (user == null) {
            return null;
        }
        // 获取用户当前位置对象
        EgObject pos = user.getPos();
        if (pos != null) {
            pos = posObjectService.pos(pos.getType().getOtid(), pos.getId());
        }
        if (pos != null) {
            user.setPos(pos);
            // 获取用户当前位置的角色信息
            EgRole posRole = userPurviewService.role(pos, user.getId(), user.getRole());
            if (posRole != null) {
                user.setRole(posRole);
            } else {
                EgRole role = user.getRole();
                role.setName(configInfo.roleName(role.getRid(), EgScope.WULIN));
            }
        } else { // pos为空，说明该用户在江湖
            EgRole role = user.getRole();
            role.setName(configInfo.roleName(role.getRid(), EgScope.WULIN));
            pos = configInfo.jianghu();
            user.setPos(pos);
        }
        // 设置账户信息
        EgAcount acount = acountService.query(user.getAcount().getId());
        user.setAcount(acount);
        return user;
    }

    /**
     * 获取用户自己的信息（详情或用户表中基本信息）
     * 
     * @param id
     * @param bDetail
     * @return
     * @throws Exception
     */
    public EgUser getUser(Long id, Boolean bDetail) throws Exception {
        // 返回所有详情信息
        if (bDetail != null && bDetail) {
            return this.detail(id);
        } else { // 否则只返回用户表中的基本信息
            EgUserEntity entity = userMapper.selectByPrimaryKey(id);
            if (entity == null) {
                return null;
            }
            return entity.createUser();
        }
    }

    /**
     * 获取用户的基本要素信息（ID、名称、头像）
     * 
     * @param id
     * @return
     * @throws Exception
     */
    public EgUser getUserBasic(Long id) throws Exception {
        EgUserEntity entity = userMapper.selectByPrimaryKey(id);
        return entity != null ? entity.createUserBasic() : null;
    }

    /**
     * 根据用户ID，获取用户所在位置权限
     * 
     * @param id
     * @return
     */
    public EgRole mypurview(Long id) throws Exception {
        EgUser user = this.detail(id);
        return user == null ? null : user.getRole();
    }

    /**
     * 根据钉钉用户唯一标识，查找用户
     * 
     * @param u_Id
     * @return
     * @throws Exception
     */
    public EgUser findByUserId(String u_Id) throws Exception {
        if (StringUtils.isNotBlank(u_Id)) {
            EgUserEntity entity = new EgUserEntity();
            entity.setUid(u_Id);
            entity = userMapper.selectOne(entity);
            if (entity != null) {
                return entity.createUser();
            }
        }
        return null;
    }

    /**
     * 判断用户名称是否重复
     * 
     * @param id
     * @param name
     * @return
     * @throws Exception
     */
    public boolean nameValidate(Long id, String name) throws Exception {
        Example example = new Example(EgUserEntity.class);

        if (StringUtils.isNotBlank(name)) {
            example.and().andEqualTo("name", name);
            if (id != null && id > 0) {
                example.and().andNotEqualTo("id", id);
            }

            int count = userMapper.selectCountByExample(example);
            return count == 0;
        }
        return true;
    }

    /**
     * 获取当前登录用户所在门派信息
     * 
     * @return
     * @throws Exception
     */
    public EgObject currentFaction() throws Exception {
        // 1、获取当前登录用户Id
        // String token = request.getHeader("Authorization");
        Long uid = (Long) request.getAttribute("userId");
        // 2、获取当前用户
        EgUser user = getUser(uid, false);
        // 3、获取当前用户所在位置
        EgObject pos = user.getPos();
        // 4、如果用户当前位置为null，返回江湖对象
        if (pos == null || pos.getId() == 0) {
            pos = configInfo.jianghu();
            return pos;
        }
        // 5、根据位置Id和位置类型查找位置对象
        pos = posObjectService.pos(pos.getType().getOtid(), pos.getId());
        if (pos != null) {
            // 6、如果位置对象为门派，返回门派对象
            if (pos instanceof EgFaction)
                return pos;
            // 7、如果位置对象为驿馆，查找驿馆所属门派信息，返回门派
            else if (pos instanceof EgTavern) {
                EgObject faction = ((EgTavern) pos).getFaction();
                if (faction != null && faction.getId() > 0)
                    return faction;
            }
        }
        // 8、否则，返回江湖对象
        pos = configInfo.jianghu();
        return pos;
    }

    /**
     * 将用户表中位置为驿馆的更新为该驿馆隶属的门派或江湖(用于删除驿馆操作)
     * 
     * @param egid
     * @param fid
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public Boolean changeUsersPos(Long egid, Long fid) throws Exception {
        Example example = new Example(EgUserEntity.class);
        example.and().andEqualTo("posOid", egid).andEqualTo("posOtype", EgOType.TAVERN);
        EgUserEntity entity = new EgUserEntity();
        if (fid == null || fid == 0) {
            entity.setPosOid(0L);
            entity.setPosOtype(EgOType.JIANGHU);
        } else {
            entity.setPosOid(fid);
            entity.setPosOtype(EgOType.FACTION);
        }
        int upCount = userMapper.updateByExampleSelective(entity, example);
        return upCount > 0 ? true : false;
    }
}
